﻿using Global.Impl.Server;
using System.Collections.Generic;
using System.Xml.Linq;
using System.Linq;
using Global.Interfaces.Server;
using System;
using System.IO;

namespace Server.BuddyLists
{
    internal static class BuddyHandler
    {
        private static readonly string fileBuddies = @"BuddyLists\buddies.xml";
        //private static readonly string fileBuddies = @"C:\Users\cln\Documents\Visual Studio 2008\Projects\Uni\P2P Project\sMessenger\Server\bin\Debug\BuddyLists\buddies.xml";
        private static readonly string fileOnline = @"BuddyLists\onlinelist.xml";
        //private static readonly string fileOnline = @"C:\Users\cln\Documents\Visual Studio 2008\Projects\Uni\P2P Project\sMessenger\Server\bin\Debug\BuddyLists\onlinelist.xml";
        private static readonly object lockObject = new object();

        public static List<Buddy> GetBuddies(string username)
        {
            if (!File.Exists(fileBuddies))
                throw new FileNotFoundException("Could not find file: " + fileBuddies);

            var buddyStatus = GetAllBuddyStatus();
            var document = XElement.Load(fileBuddies);

            var buddies = from b in document.Descendants(username).Elements("buddy")
                          select new
                          {
                              Username = b.Element("username").Value,
                              Ip = b.Element("ip").Value,
                              Port = int.Parse(b.Element("port").Value),
                              PublicKey = b.Element("publickey").Value
                          };

            var buddiesForUser = new List<Buddy>();
            Buddy tmpBuddy;
            foreach (var buddy in buddies)
            {
                tmpBuddy = new Buddy(buddy.Username, buddy.Ip, buddy.Port, buddy.PublicKey, false);
                foreach (var item in buddyStatus)
                {
                    if (item.Username == buddy.Username)
                    {
                        tmpBuddy.LastActive = item.LastActive;
                        tmpBuddy.IsOnline = item.IsOnline;
                        tmpBuddy.Ip = item.Ip;
                        tmpBuddy.Port = item.Port;
                        break;
                    }
                }
                buddiesForUser.Add(tmpBuddy);
            }

            return buddiesForUser;
        }

        public static bool AddBuddy(string username, string buddyUsername)
        {
            if (!File.Exists(fileBuddies))
                throw new FileNotFoundException("Could not find file: " + fileBuddies);

            var document = XElement.Load(fileBuddies);

            var exist = document.Descendants(username);

            if (exist.Count() > 0)
            {
                var userElement = exist.SingleOrDefault();
                var existBuddy = (from b in userElement.Descendants("buddy")
                                  where b.Element("username").Value == buddyUsername
                                  select new { Found = true }).SingleOrDefault();

                if (existBuddy != null)
                    return false;

                userElement.Add(
                    new XElement("buddy",
                        new XElement("username", buddyUsername)
                    )
                );
                document.Save(fileBuddies);

                return true;
            }
            else
            {
                document.Add(
                    new XElement(username,
                        new XElement("buddy",
                            new XElement("username", buddyUsername)
                        )
                    )
                );
                document.Save(fileBuddies);
                return true;
            }
        }

        public static List<IBuddy> GetAllBuddyStatus()
        {
            if (!File.Exists(fileBuddies))
                throw new FileNotFoundException("Could not find file: " + fileOnline);

            var document = XElement.Load(fileOnline);

            var buddies = from b in document.Descendants("buddy")
                          select new
                          {
                              Username = b.Element("username").Value,
                              LastSeen = DateTime.Parse(b.Element("lastseen").Value),
                              IP = b.Element("ip").Value,
                              Port = Int32.Parse(b.Element("port").Value)
                          };

            List<IBuddy> buddyStatus = new List<IBuddy>();
            IBuddy buddyItem;
            foreach (var buddy in buddies)
            {
                buddyItem = new Buddy(buddy.Username, buddy.IP, buddy.Port, string.Empty, buddy.LastSeen >= DateTime.Now.AddMinutes(-1));
                buddyItem.LastActive = buddy.LastSeen;
                buddyStatus.Add(buddyItem);
            }
            return buddyStatus;
        }

        public static void Buddyseen(string username, string ip)
        {
            if (!File.Exists(fileBuddies))
                throw new FileNotFoundException("Could not find file: " + fileOnline);

            var document = XElement.Load(fileOnline);

            var buddy = (from b in document.Descendants("buddy")
                        where b.Element("username").Value == username
                        select b).SingleOrDefault();

            if (buddy == null)
                return;

            buddy.SetElementValue("lastseen", DateTime.Now);
            buddy.SetElementValue("ip", ip);

            document.Save(fileOnline);
        }

        public static void Buddyseen(string username, string ip, string port)
        {
            if (!File.Exists(fileBuddies))
                throw new FileNotFoundException("Could not find file: " + fileOnline);

            var document = XElement.Load(fileOnline);

            var buddy = (from b in document.Descendants("buddy")
                         where b.Element("username").Value == username
                         select b).SingleOrDefault();

            if (buddy == null)
                return;

            buddy.SetElementValue("lastseen", DateTime.Now);
            buddy.SetElementValue("ip", ip);
            buddy.SetElementValue("port", port);

            document.Save(fileOnline);
        }
    }
}
